package juc.popular.aqs;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
import java.util.random.RandomGenerator;
import java.util.stream.IntStream;

/**
 * 屏障
 * 可以让一组线程达到一个屏障时被阻塞,直到最后一个线程达到屏障时,阻塞的线程才能继续执行
 *
 * @author 王霄
 * @date 2021/9/23 12:56
 **/
public class CyclicBarrierDemo {


    public static void main(String[] args) {

        //运动员姓名
        String[] nameArr = new String[]{"博尔特" , "刘翔" , "苏炳添" , "科比" , "乔丹"};

        //运动员成绩
        double[] scopeArr = RandomGenerator.getDefault()
                .doubles(9, 10)
                .limit(nameArr.length)
                .toArray();

        //号令枪
        CyclicBarrier commandGun = new CyclicBarrier(nameArr.length);

        IntStream.range(0, nameArr.length)
                .forEach(i -> new Jock(commandGun, nameArr[i], scopeArr[i]).start());

    }

    public static class Jock extends Thread {
        private final CyclicBarrier commandGun;
        private final String name;
        private final double scope;

        public Jock(CyclicBarrier commandGun, String name, double scope) {
            this.commandGun = commandGun;
            this.name = name;
            this.scope = scope;
        }

        @Override
        public void run() {
            try {
                if (name.equals("博尔特")) {
                    TimeUnit.SECONDS.sleep(3);
                }
                System.out.printf("%s已经准备好了%n" , name);
                commandGun.await();
                TimeUnit.MILLISECONDS.sleep((long) (scope * 1000));
                System.out.printf("%s:  %.2f秒%n" , name, scope);
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }
}
